2000年以降の問題と少し関係のあることについて 25時はやってこない 編集部:舩本昇竜
コンピュータ2000年問題が、エラい問題になっており、私の知人・友人は もちろん、読者の方の多くも、「Y2k部隊」として正月無しで仕事。…とのコト。 いやハヤ、ご苦労さまです。 さて、すでにコンピュータ2000年問題の「1900年と2000年を間違 えてしまう云々」のアレコレに関しては、耳タコ状態だと思いますので、ここで は、もう少し本質的な問題について、オツマミ的に触れてみます。 ○一見正常なプログラムでもコンピュータは死亡する事実 まずは、次のプログラムを見て下さい。そして、実際に実行してみてください。 ◎ 単純に10秒待つソース ● 単純に10秒待ってみる=非対応メニューです どうですか。おそらく、なんの問題もなく実行出来たと思います。実際、「基 本的」に、このプログラムそのもののに問題はありません。確率なんてものを持 ち出すと、99.988%うまく行く計算になります。 逆に言えば、残り「0.012%」の確率でうまくいきません。計算上うまく いきません。アブソリュートうまくいきません。事実、このプログラムはある条 件下で、確実に暴走します。同じプログラムなのに、どうして、このような動作 の違いがでるのでしょうか。 ○便利な機能「1/100秒タイマ」 まずは、関連知識から押さえましょう。 X68kには、「1/100秒タイマ」が備わっており、電源投入、または本体リセッ ト直後から動き出します。この時、タイマに連動するカウンタの値は0で、文字 通り1/100秒経過するごとに1増え、ちょうど1秒で100、1分で6000、1時間で 360000になります。また、プログラムの中で使われている「ONTIME()」という関 数は、この 1/100秒タイマ用カウンタの現在値を知る関数で、この関数を使うこ とで、電源投入、または本体リセットからどの位時間が経過したかを知ることが 出来ます。例えば、上のプログラム中の「st=ONTIME();」行実行時のst の値が 816000の場合、電源投入、または本体リセットから、2時間16分経過している ということになります。 つまり、この1/100秒タイマを使って、実際に「10秒待つ」には「カウンタ が1000進む」のを待てばいいワケです。そして、上のプログラムでも実際にその ようにして10秒待っているのです。 ○「カウンタリセット」というワナ このように、原理的に全く問題がないように見えても、それでもやはり、 「0.012%」の確率で、確実に暴走はします。いったい、何が暴走の原因な のでしょう? その答は、ズバリ「カウンタのリセット(0に戻す)」にあります。 X68kの1/100秒カウンタの場合、丸1日、24時間ちょうどでカウンタがいっ たんリセットされます。そういう仕組みなのです。つまり、0から始まった 1/100秒カウンタは、 時間 カウンタ値 00時00分00秒00 0 00時00分00秒01 1 00時00分00秒02 2 : : 23時59分59秒97 8639997 23時59分59秒98 8639998 23時59分59秒98 8639999 24時00分00秒00 0(ここで、リセット) 24時00分00秒01 1 24時00分00秒02 2 となり、単純にONTIME()の値を見ただけでは、「00時00分00秒02」なのか「24時 00分00秒02」なのかを判別することが出来ないのです。 さらに問題は複雑化し、例えば、上記のプログラムで「23時59分53秒00(カウ ンタ値=8639300)」から10秒待つ場合、プログラム上では、単純に10秒加え た「24時00分03秒00(カウンタ値=8640300)」を待つことになります。しかし、 実際にカウンタは「24時00分00秒00(カウンタ値=8640000→0)」でいったんリ セットされてしまうので、どんなに長い時間待ったとしても、カウンタ値が 8640000以上になることはありません。それでも、プログラムは絶対にありえな い「カウンタ値=8640300」を永遠に待つのです。あぁ、悲しい。そう思っても、 待ち続けるのです。 結局、上記のプログラムでは、プログラムの実行時(精確には、 「st=ONTIME();」行の実行時)のタイマの値が、8639000~8639999(23時59分 50秒00~23時59分59秒99)であると、少なくとも、プログラマが思った通りの 動作をしなくなるのです。一日=24時間=86400秒中の10秒。それが、 「0.012%」の根拠なのです。 ○単純だが奥は深い問題 例えば、「(符号無し)16bitカウンタ」と呼ばれるカウンタは、単位時間が どうであれ、65535の次の値は、問答無用で0になります。つまり、リセットされ るのです。よって、66000あたりの数字を目標値にしてしまうと、それだけで、 絶望的アウトなわけです。もう少し具体的かつ技術的な局面でこの例を考えると、 カウンタが符号無し16bitなのに対し、比較用に符号あり32bitレジスタを使用す ると、簡単にハマってしまいます。「まさかそんな」と思っていても、結構ハマ るものです。ビット数は、関係ありません。カウンタなんてモノは、いつかどこ かで、必ずリセットされるものなのです。 この、「絶対に来ない目標値をひたすら待ち続ける」という無限ループ地獄で すが、なにもこの問題、X68kの1/100秒タイマーに限った話ではありません。そ して、案外、この「絶対に来ない目標値」、「絶対に来ない目標値を待つプログ ラム」は、そのへんに存在し、どんなに対策をしても、間違いなく発生します。 要は、その食い止められずに発生した問題の程度の問題。人が死んでしまうコト もあれば、お湯が沸かないコトもある。そういうモノなのです。 ところで、上の「10秒待つプログラム」。タイマーリセットを考慮して、正 しく書き直せますか? (一応ここまで:以下、よたばなし) ○老後の心配 2038年問題は、おもいっきりもなにも、カウンタの問題そのものです。そ の正体は、32bitの1秒で+1されるカウンタが、1970年からスタートして います。というもの。ここで注目したいのが、「秒カウンタ」であることと 「32bit」であること。さらには、その頃まで生きている可能性が高いこと。 それぞれに注目してみると、まず、「1秒で+1されても、1日86400カウン ト。32bitのカウンタなら、あふれることはない」or「原理上あふれることはわ かっていても、半世紀も先の話なら、システムそのものも変わっているだろう」。 私だってそう考えますし、世界中の多くのプログラマもそう考えるでしょう。し かし、約40年後には実際にあふれてしまうのです。あと、40年もあるのだか ら、と考えても、何十年もの間、古いシステムのままひきづられたデータが山の ようにあることは、2000年問題が証明してくれました。 また、うまい具合に生き延びていれば、2038年なんてのは、今の電脳倶楽 部読者の多くが年金生活(年金という制度が変わるとか、存在し続けるか、なん かは別問題)をしているはず。さらに、それらは、コンピュータで管理(けっ) されているはず。ヤレヤレ。 (EOF)